package com.tanhua.server.service;

import com.tanhua.commons.templates.OssTemplate;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.mongo.Visitors;
import com.tanhua.domain.vo.ErrorResult;
import com.tanhua.domain.vo.MovementsVo;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.VisitorsVo;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.PublishApi;
import com.tanhua.dubbo.api.mongo.RecommendUserApi;
import com.tanhua.dubbo.api.mongo.VisitorsApi;
import com.tanhua.server.Interceptor.UserHolder;
import com.tanhua.server.utils.RelativeDateFormat;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.xml.ws.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class MovementsService {

    @Autowired
    private OssTemplate ossTemplate;


    @Reference
    private PublishApi publishApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    @Reference
    private VisitorsApi visitorsApi;

    @Reference
    private RecommendUserApi recommendUserApi;


    @Autowired
    private MovementsMQService movementsMQService;

    @Autowired(required = false)
    private RocketMQTemplate rocketMQTemplate;
    //冻结发布动态
    private static final String freezingPublish = "userFreezing_publish_";

    /**
     * 发布朋友圈
     * @param publish
     * @param imageContent
     * @return
     */
    public ResponseEntity<Object> saveMovements(Publish publish, MultipartFile[] imageContent) throws IOException {
        //1. 获取登陆的用户Id
        long userId = UserHolder.getUserId();
        //判断用户是否被冻结
        Boolean b = redisTemplate.hasKey(freezingPublish + userId);
        if(b!=null) {
            if (b) {
                return ResponseEntity.status(500).body(ErrorResult.freezingError());
            }
        }

        //2. 把图片上传到阿里云
        List<String> medisList = new ArrayList<>();
        if(imageContent!=null && imageContent.length>0) {
            for (MultipartFile multipartFile : imageContent) {
                String imageUrl = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                medisList.add(imageUrl);
            }
        }

        //3.把图片的地址设置给publish, 用户的id
        publish.setUserId(userId);
        publish.setMedias(medisList);
        //给朋友圈设置一个id
        publish.setId(ObjectId.get());
        //设置朋友圈的状态
        publish.setState(0);


        //4. 保存朋友圈
        publishApi.save(publish);

        //发送消息
        movementsMQService.publishMsg(publish.getId().toString());

        //往rocketmq发送消息
        rocketMQTemplate.convertAndSend("tanhua-publish",publish.getId().toString());

        //5. 返回响应
        return ResponseEntity.ok(null);

    }

    /**
     * 查询好友的朋友圈
     * @param page  当前页
     * @param pageSize  页面大小
     * @return
     */
    public ResponseEntity<Object> queryPublishList(Integer page, Integer pageSize) {
        //1. 获取当前登陆的用户id
        long userId = UserHolder.getUserId();
        //2. 查询好友的朋友圈，得到PageReuslt,注意： 我这里的pageREsult存储的是Publish
        PageResult pageResult =  publishApi.findByTimeLine(page,pageSize,userId);
        //把pageREsult的items的publish转换为movementVos
        setMovementsVo(pageResult);
        return ResponseEntity.ok(pageResult);
    }

    public void setMovementsVo(PageResult pageResult) {
        //3. 得到分页的对象Items, List<Publish>
        List<Publish> publishList= (List<Publish>) pageResult.getItems();

        //4. 遍历所有的Publish，把publish构建为MovementsVo
        List<MovementsVo> voList = new ArrayList<>();
        if(publishList!=null){
            for (Publish publish : publishList) {
                MovementsVo vo  = new MovementsVo();
                //查询朋友圈发布人的用户信息
                UserInfo userInfo = userInfoApi.findById(publish.getUserId());
                if(userInfo!=null){
                    BeanUtils.copyProperties(userInfo,vo);
                    if(userInfo.getTags()!=null){
                        vo.setTags(userInfo.getTags().split(","));
                    }
                }
                //把publish信息转义到movementsVo
                BeanUtils.copyProperties(publish,vo);
                //id
                vo.setId(publish.getId().toString());
                //图片
                vo.setImageContent(publish.getMedias().toArray(new String[]{}));
                //距离
                vo.setDistance("50米");
                //发布时间 ,发布朋友圈距离今天的时间
                vo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

                String likeKey ="publish_like_comment_"+UserHolder.getUserId()+"_"+publish.getId();
                String loveKey ="publish_love_comment_"+UserHolder.getUserId()+"_"+publish.getId();

                if(redisTemplate.hasKey(likeKey)){
                    //如果redis包含了指定的key，则代表了该用户对该朋友圈已经点赞了
                    vo.setHasLiked(1); //是否点赞
                }else {
                    vo.setHasLiked(0); //是否点赞
                }
                if(redisTemplate.hasKey(loveKey)) {
                    vo.setHasLoved(1); //是否喜欢
                }else{
                    vo.setHasLoved(0); //是
                }
                voList.add(vo);
            }
        }


        //5. 修改PageResult对象存储的内容
        pageResult.setItems(voList);
    }


    /**
     *接口名称：推荐动态
     * 接口路径：GET/movements/recommend
     */
    public ResponseEntity<Object> queryRecommendPublishList(Integer page, Integer pageSize) {
        //1. 得到当前登陆的用户Id
        long userId = UserHolder.getUserId();
        //2 查询大数据团队给我们推送的朋友圈
        PageResult pageResult = findByRecommend(page,pageSize);
        if(pageResult==null) {
            pageResult = publishApi.queryRecommendPublishList(page, pageSize, userId);
        }
        //publish---movementsVo
        setMovementsVo(pageResult);
        return ResponseEntity.ok(pageResult);
    }

    //查询redis得到大数据团队给我们推送的朋友圈
    private PageResult findByRecommend(Integer page, Integer pageSize ) {
        //1. 从redis中取出推荐的朋友圈的pid
        String value = redisTemplate.opsForValue().get("QUANZI_PUBLISH_RECOMMEND_" + UserHolder.getUserId());

        //2. 如果取出为null，直接返回null。
        if(value==null){
            return null;
        }
        //1,2,3,45,6,7,8,9,10
        String[] pids = value.split(",");

        //3. 计算开始索引值与结束的索引值，   1,2,3,4，5,6,7,8,9,10      1 每页3条
        int  startIndex = (page-1)*pageSize;//开始索引值
        List<Long> pidList = new ArrayList<>();
        if(startIndex<pids.length){
            //计算结束索引值
            int endIndex = startIndex+pageSize-1;//0+3-1=2
            if(endIndex>=pids.length){
                endIndex = pids.length-1;
            }
            //根据startIndex与endIndex 取出pid出来
            for (int i = startIndex; i <=endIndex ; i++) {
                String pid = pids[i];
                //把pid添加到一个集合中
                pidList.add(Long.valueOf(pid));
            }
        }
        //根据pid查找动态
        List<Publish> publishList = publishApi.findByPid(pidList);
        //4. 根据索引值查找对应的朋友圈，构建一个Pageresult对象返回
        return new PageResult(page,pageSize,pids.length,publishList);
    }


    //查询单个动态
    public ResponseEntity<Object> queryMovementsById(String publishId) {
        //1. 根据id查出一个publish的对象
        Publish publish = publishApi.findById(publishId);
        //2. 把publish转换movementsVo
        MovementsVo vo  = new MovementsVo();
        //查询朋友圈发布人的用户信息
        UserInfo userInfo = userInfoApi.findById(publish.getUserId());
        if(userInfo!=null){
            BeanUtils.copyProperties(userInfo,vo);
            if(userInfo.getTags()!=null){
                vo.setTags(userInfo.getTags().split(","));
            }
        }
        //把publish信息转义到movementsVo
        BeanUtils.copyProperties(publish,vo);
        //id
        vo.setId(publish.getId().toString());
        //图片
        vo.setImageContent(publish.getMedias().toArray(new String[]{}));
        //距离
        vo.setDistance("50米");
        //发布时间 ,发布朋友圈距离今天的时间
        vo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

        String likeKey ="publish_like_comment_"+UserHolder.getUserId()+"_"+publish.getId();
        String loveKey ="publish_love_comment_"+UserHolder.getUserId()+"_"+publish.getId();

        if(redisTemplate.hasKey(likeKey)){
            //如果redis包含了指定的key，则代表了该用户对该朋友圈已经点赞了
            vo.setHasLiked(1); //是否点赞
        }else {
            vo.setHasLiked(0); //是否点赞
        }
        if(redisTemplate.hasKey(loveKey)) {
            vo.setHasLoved(1); //是否喜欢
        }else{
            vo.setHasLoved(0); //是
        }
        return ResponseEntity.ok(vo);
    }


    /**
     * 接口名称：用户动态
     */
    public ResponseEntity<Object> queryMyPublishList(Integer page, Integer pagesize, Long userId) {
        // 1.获取登录用户id
        if (userId == null) {
            // 如果未传入userId，就获取当前用户id
            userId = UserHolder.getUserId();
        }

        // 2.调用服务提供者分页查询该用户的个人动态
        PageResult pageResult = publishApi.queryMyPublishList(page, pagesize, userId);

        // 3.调用公共方法，设置返回结果
        setMovementsVo(pageResult);

        return ResponseEntity.ok(pageResult);
    }


    //最近访客
    public ResponseEntity<Object> queryVisitors() {
        //1. 判断是否记录了当前用户的上一次今日首页时间
        long userId = UserHolder.getUserId();
        String  key = "visitors_time_"+UserHolder.getUserId();
        List<Visitors> visitorsList = null;
        if(redisTemplate.hasKey(key)){
            //你不是第一次进入到首页了，是有上一次进入的时间
            //获取你上一次的访问时间
            long lastTime = Long.parseLong(redisTemplate.opsForValue().get(key));
            visitorsList = visitorsApi.queryVisitors(userId,lastTime,5);
        }else{
            //你是首次进入首页
            visitorsList =visitorsApi.queryVisitors(userId,null,5);
        }

        //记录当前的系统时间到redis中，作为你下一次的上一次访问时间
        redisTemplate.opsForValue().set(key,System.currentTimeMillis()+"");

        //2. 遍历Visitors ，把数据取出封装到Visitorsvo对象
        List<VisitorsVo> visitorsVoList = new ArrayList<>();
        if(visitorsList!=null){
            for (Visitors visitors : visitorsList) {
                //每一个visitors都对应一个vo
                VisitorsVo vo  = new VisitorsVo();
                //查询访客用户信息
                UserInfo userInfo = userInfoApi.findById(visitors.getVisitorUserId());
                if(userInfo!=null){
                    BeanUtils.copyProperties(userInfo,vo);
                    if(userInfo.getTags()!=null){
                        vo.setTags(userInfo.getTags().split(","));
                    }
                }
                //设置缘分值
                Long score = recommendUserApi.queryScore(userId, visitors.getVisitorUserId());
                vo.setFateValue(score.intValue());
                visitorsVoList.add(vo);
            }
        }

        return ResponseEntity.ok(visitorsVoList);
    }
}
